using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;



namespace Trebuchet
{


    public partial class TrebuchetPrime : Form
    {
        Dictionary<ShortcutCollection.ShortcutType, ShortcutCollection> shortcuts = new Dictionary<ShortcutCollection.ShortcutType, ShortcutCollection>();

        [DllImport("user32.dll")]
        public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
        [DllImport("User32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
        static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        Dictionary<string, Shortcut> links = new Dictionary<string, Shortcut>();
        Preferences preferences = null;
        //ShortcutCollection shortcuts = new ShortcutCollection();

        public TrebuchetPrime()
        {
            shortcuts.Add(ShortcutCollection.ShortcutType.Cache, ShortcutCollection.Read(ShortcutCollection.ShortcutType.Cache));
            shortcuts.Add(ShortcutCollection.ShortcutType.StartMenu, new ShortcutCollection());
            shortcuts.Add(ShortcutCollection.ShortcutType.User, ShortcutCollection.Read(ShortcutCollection.ShortcutType.User));
            InitializeComponent();
            GetStartMenuShortcuts();

            BuildLinks();

            //None = 0,
            //Alt = 1,
            //Control = 2,
            //Shift = 4,
            //Windows = 8

            preferences = Preferences.Read();
            if (preferences == null)
            {
                PreferencesForm form = new PreferencesForm();
                form.Preferences = null;
                if (form.ShowDialog() == DialogResult.OK)
                {
                    preferences = form.Preferences;
                }
            }
            else
            {
                bool success = RegisterHotKey(this.Handle, this.GetType().GetHashCode(), preferences.HotKeyModifiers, (int)preferences.HotKey);
            }
        }

        private void BuildLinks()
        {
            links = new Dictionary<string, Shortcut>();
            string[] predefinedCommands = ((string)("exit,edit,hide,new,settings,help")).Split(',');
            foreach (string command in predefinedCommands)
            {
                if (!links.ContainsKey(command))
                    links.Add(command, null);
            }
            foreach (Shortcut shortcut in shortcuts[ShortcutCollection.ShortcutType.User])
            {
                if (!links.ContainsKey(shortcut.Name))
                    links.Add(shortcut.Name, shortcut);
            }
            foreach (Shortcut shortcut in shortcuts[ShortcutCollection.ShortcutType.Cache])
            {
                if (!links.ContainsKey(shortcut.Name))
                    links.Add(shortcut.Name, shortcut);
            }
            foreach (Shortcut shortcut in shortcuts[ShortcutCollection.ShortcutType.StartMenu])
            {
                if (!links.ContainsKey(shortcut.Name))
                    links.Add(shortcut.Name, shortcut);
            }
            

            comboBox1.Items.Clear();
            foreach (string key in links.Keys)
            {
                comboBox1.Items.Add(key);
            }
        }
        private void BuildDirectoryLinks()
        {
            string currentPath = comboBox1.Text + "\\";
            if (Directory.Exists(currentPath))
            {
                DirectoryInfo directoryInfo = new DirectoryInfo(currentPath);

                if (directoryInfo != null)
                {
                    //comboBox1.Items.Clear();
                    foreach (DirectoryInfo subDirectory in directoryInfo.GetDirectories())
                        comboBox1.Items.Add(subDirectory.FullName);
                    foreach (FileInfo file in directoryInfo.GetFiles())
                        comboBox1.Items.Add(file.FullName);
                }
            }
            else
                BuildLinks();

            //SendMessage(comboBox1.Handle, 227, new IntPtr(277), new IntPtr(0));
            //comboBox1.Text = currentPath;
            
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x0312)
                ShowMe();
            base.WndProc(ref m);
        }

        private void Execute()
        {
                string command = comboBox1.Text;
            try
            {
                switch (command.ToLower())
                {
                    case "exit":
                        command = null;
                        this.Close();
                        break;
                    case "hide":
                        HideMe();
                        comboBox1.Text = string.Empty;
                        command = null;
                        break;
                    case "new":
                        ShortcutForm newForm = new ShortcutForm();
                        newForm.Shortcuts = shortcuts[ShortcutCollection.ShortcutType.User];
                        newForm.Mode = ShortcutForm.FormMode.Create;
                        newForm.ShowDialog();
                        BuildLinks();
                        comboBox1.Text = string.Empty;
                        command = null;
                        break;
                    case "edit":
                        ShortcutForm editForm = new ShortcutForm();
                        editForm.Shortcuts = shortcuts[ShortcutCollection.ShortcutType.User];
                        editForm.Mode = ShortcutForm.FormMode.Edit;
                        editForm.ShowDialog();
                        BuildLinks();
                        comboBox1.Text = string.Empty;
                        command = null;
                        break;
                    case "settings":
                        PreferencesForm preferencesForm = new PreferencesForm();
                        preferencesForm.Preferences = preferences;
                        if (preferencesForm.ShowDialog() == DialogResult.OK)
                            preferences = preferencesForm.Preferences;

                        comboBox1.Text = string.Empty;
                        command = null;
                        break;
                    case "help":
                        comboBox1.Text = string.Empty;
                        command = null;
                        throw new NotImplementedException();
                        break;

                }
                if (!string.IsNullOrEmpty(command))
                {
                    bool inList = false;
                    Shortcut shortcut = null;
                    if (links.ContainsKey(command))
                    {
                        inList = true;
                        if (!string.IsNullOrEmpty(links[command].Command))
                            shortcut = links[command];
                    }
                    ProcessStartInfo psi = null;
                    if (shortcut != null)
                    {
                        psi = new ProcessStartInfo(shortcut.Command);
                        if (!string.IsNullOrEmpty(shortcut.Arguements))
                            psi.Arguments = shortcut.Arguements;
                        if (!string.IsNullOrEmpty(shortcut.StartupPath))
                            psi.WorkingDirectory = shortcut.StartupPath;
                    }
                    else
                        psi = new ProcessStartInfo(command);
                    
                    Process process = new Process();
                    process.StartInfo = psi;
                    process.Start();
                    comboBox1.Text = string.Empty;
                    if (!inList)
                    {
                        shortcut = new Shortcut();
                        shortcut.Command = command;
                        shortcut.Name = command;
                        shortcuts[ShortcutCollection.ShortcutType.Cache].Add(shortcut);
                        shortcuts[ShortcutCollection.ShortcutType.Cache].Save();
                        BuildLinks();
                        //links.Add(command, string.Empty);
                        //comboBox1.Items.Add(command);
                    }
                    HideMe();
                }
            }
            catch (System.Exception exp)
            {
                if (MessageBox.Show("Shortcut not found, would you like to create one?", "Shortcut not found", MessageBoxButtons.YesNo, MessageBoxIcon.Error) == DialogResult.Yes)
                {
                    ShortcutForm form = new ShortcutForm();
                    form.Mode = ShortcutForm.FormMode.Create;
                    form.Name = command;
                    form.Shortcuts = shortcuts[ShortcutCollection.ShortcutType.User];
                    form.ShowDialog();
                    BuildLinks();
                }
                //MessageBox.Show(exp.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            
        }

        private void GetStartMenuShortcuts()
        {
            string startMenuPath = Environment.GetFolderPath(Environment.SpecialFolder.StartMenu);
            DirSearch(startMenuPath);

            string pattern = @"(?<Drive>\w):\\(?<RootFolder>(\w|\s|\.)*)\\(?<UserName>(\w|\s|\.)*)(?<TheRest>(\w|\s|\\|\.)*)";
            Regex regex = new Regex(pattern);
            MatchCollection collection = regex.Matches(startMenuPath);
            string rootFolder = collection[0].Groups["RootFolder"].Value;
            string drive = collection[0].Groups["Drive"].Value;
            string username = collection[0].Groups["UserName"].Value;
            string theRest = collection[0].Groups["TheRest"].Value;

            string allUsersStartMenu = string.Empty;

            // There has got to be a better way to get the path to the all users start menu.
            if (rootFolder == "Documents and Settings")
            {
                // For XP
                allUsersStartMenu = string.Format("{0}:\\{1}\\All Users\\{2}",
                    drive, rootFolder, theRest);
            }
            else
            {
                // For Vista
                allUsersStartMenu = string.Format("{0}:\\{1}\\Public\\{2}",
                    drive, rootFolder, theRest);
            }
            
            DirSearch(allUsersStartMenu);
            //DirSearch(@"C:\Documents and Settings\All Users\Start Menu");

            //shortcuts.Save();
            //ShortcutCollection collection2 = ShortcutCollection.Read(@"c:\test.xml");
            
        }
        //List<string> links = new List<string>();
        

        void DirSearch(string directory)
        {
            if (Directory.Exists(directory))
            {
                try
                {
                    foreach (string d in Directory.GetDirectories(directory))
                    {
                        foreach (string f in Directory.GetFiles(d, "*.lnk"))
                        {
                            string key = f.Substring(f.LastIndexOf("\\") + 1, f.Length - f.LastIndexOf("\\") - 5);
                            string value = f;
                            if (!links.ContainsKey(key))
                            {
                                //links.Add(key, value);
                                Shortcut shortcut = new Shortcut();
                                shortcut.Command = value;
                                shortcut.Name = key;
                                shortcuts[ShortcutCollection.ShortcutType.StartMenu].Add(shortcut);
                            }
                        }
                        DirSearch(d);

                    }
                }
                catch (System.Exception excpt)
                {
                    Console.WriteLine(excpt.Message);
                }
            }
        }

        private void comboBox1_KeyDown(object sender, KeyEventArgs e)
        {
            switch(e.KeyValue)
            {
                case 13:
                    Execute();
                    break;
                case 27:
                    HideMe();
                    break;
                case 220:
                    //comboBox1.Text += "\\";
                    BuildDirectoryLinks();
                    break;
            }
        }

        private void ShowMe()
        {
            Show();
            WindowState = FormWindowState.Normal;
            Activate();
            comboBox1.Focus();
        }

        private void HideMe()
        {
            //WindowState = FormWindowState.Minimized;
            Hide();

        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            ShowMe();
            //if (WindowState == FormWindowState.Normal)
            //{
            //    HideMe();
            //}
            //else
            //{
            //    ShowMe();
            //}
        }
    }
}